package service

import (
	"context"
	"dubbo.apache.org/dubbo-go/v3/config"
	_ "dubbo.apache.org/dubbo-go/v3/imports"
	"encoding/json"
	"favourite/api"
	"github.com/dubbogo/grpc-go/codes"
	"github.com/dubbogo/grpc-go/status"
	"strconv"
)

var commonProvider *api.CommonClientImpl

func OK(list []int64, size int64) (*api.FavouriteList, error) {
	return &api.FavouriteList{
		VideoIdList: list,
		Size:        size,
	}, nil
}

func FAIL(err error) (*api.FavouriteList, error) {
	return nil, err
}

type FavouriteProvider struct {
	api.UnimplementedFavouriteProviderServer
}

func (s *FavouriteProvider) Add(c context.Context, favourite *api.Favourite) (*api.Favourite, error) {
	if favourite.GetUserId() == 0 || favourite.GetVideoId() == 0 {
		return nil, status.Errorf(codes.FailedPrecondition, "parameter error")
	}

	count, err := commonProvider.Count(c, &api.Query{
		Database: "douyin",
		Table:    "favourite",
		Where: []*api.Query_Condition{
			{
				Key:   []string{"user_id"},
				Value: []string{strconv.FormatInt(favourite.GetUserId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
			{
				Key:   []string{"video_id"},
				Value: []string{strconv.FormatInt(favourite.GetVideoId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
		},
	})
	if err != nil {
		return nil, err
	}

	if count.Size == 0 {

		_, err := commonProvider.Update(c, &api.Value{
			Database: "douyin",
			Table:    "favourite",
			Key:      []string{"user_id", "video_id"},
			Value:    []string{strconv.FormatInt(favourite.GetUserId(), 10), strconv.FormatInt(favourite.GetVideoId(), 10)},
		})
		if err != nil {
			return nil, err
		}
	}
	return nil, nil
}
func (s *FavouriteProvider) Del(c context.Context, favourite *api.Favourite) (*api.Favourite, error) {
	if favourite.GetUserId() == 0 || favourite.GetVideoId() == 0 {
		return nil, status.Errorf(codes.FailedPrecondition, "parameter error")
	}

	count, err := commonProvider.Count(c, &api.Query{
		Database: "douyin",
		Table:    "favourite",
		Where: []*api.Query_Condition{
			{
				Key:   []string{"user_id"},
				Value: []string{strconv.FormatInt(favourite.GetUserId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
			{
				Key:   []string{"video_id"},
				Value: []string{strconv.FormatInt(favourite.GetVideoId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
		},
	})
	if err != nil {
		return nil, err
	}

	if count.Size == 1 {

		_, err := commonProvider.Del(c, &api.Query{
			Database: "douyin",
			Table:    "favourite",
			Where: []*api.Query_Condition{
				{
					Key:   []string{"user_id"},
					Value: []string{strconv.FormatInt(favourite.GetUserId(), 10)},
					Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
				},
			},
		})
		if err != nil {
			return nil, err
		}
	}
	return nil, err
}
func (s *FavouriteProvider) CountUser(c context.Context, favourite *api.Favourite) (*api.FavouriteList, error) {
	if favourite.GetUserId() == 0 {
		return FAIL(status.Errorf(codes.FailedPrecondition, "parameter error"))
	}

	count, err := commonProvider.Count(c, &api.Query{
		Database: "douyin",
		Table:    "favourite",
		Where: []*api.Query_Condition{
			{
				Key:   []string{"user_id"},
				Value: []string{strconv.FormatInt(favourite.GetUserId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
		},
	})
	if err != nil {
		return FAIL(err)
	}
	return OK(nil, count.Size)
}

func (s *FavouriteProvider) FindUserFavouriteList(c context.Context, favourite *api.Favourite) (*api.FavouriteList, error) {
	if favourite.GetUserId() == 0 {
		return FAIL(status.Errorf(codes.FailedPrecondition, "parameter error"))
	}

	get, err := commonProvider.Get(c, &api.Query{
		Database: "douyin",
		Table:    "favourite",
		Where: []*api.Query_Condition{
			{
				Key:   []string{"user_id"},
				Value: []string{strconv.FormatInt(favourite.GetUserId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
		},
		Result: api.Query_FAVOURITE,
	})
	if err != nil {
		return FAIL(err)
	}

	var result []*api.Favourite
	err = json.Unmarshal(get.Value, &result)
	if err != nil {
		return FAIL(err)
	}

	var msg []int64
	for _, value := range result {
		msg = append(msg, value.VideoId)
	}
	return OK(msg, 0)
}
func (s *FavouriteProvider) IsFavourite(c context.Context, favourite *api.Favourite) (*api.FavouriteList, error) {
	if favourite.GetUserId() == 0 || favourite.GetVideoId() == 0 {
		return FAIL(status.Errorf(codes.FailedPrecondition, "parameter error"))
	}

	count, err := commonProvider.Count(c, &api.Query{
		Database: "douyin",
		Table:    "favourite",
		Where: []*api.Query_Condition{
			{
				Key:   []string{"user_id"},
				Value: []string{strconv.FormatInt(favourite.GetUserId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
			{
				Key:   []string{"video_id"},
				Value: []string{strconv.FormatInt(favourite.GetVideoId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
		},
	})
	if err != nil {
		return FAIL(err)
	}

	if count.Size == 1 {
		return OK(nil, 1)
	} else {
		return OK(nil, 0)
	}

}
func (s *FavouriteProvider) CountVideo(c context.Context, favourite *api.Favourite) (*api.FavouriteList, error) {
	if favourite.GetVideoId() == 0 {
		return FAIL(status.Errorf(codes.FailedPrecondition, "parameter error"))
	}

	count, err := commonProvider.Count(c, &api.Query{
		Database: "douyin",
		Table:    "favourite",
		Where: []*api.Query_Condition{
			{
				Key:   []string{"video_id"},
				Value: []string{strconv.FormatInt(favourite.GetVideoId(), 10)},
				Type:  []api.Query_Condition_ConditionType{api.Query_Condition_NE},
			},
		},
	})
	if err != nil {
		return FAIL(err)
	}

	return OK(nil, count.Size)
}

func init() {
	// 注册服务
	config.SetProviderService(&FavouriteProvider{})

	commonProvider = new(api.CommonClientImpl)
	config.SetConsumerService(commonProvider)
}
